package main

import (
	"fmt"
)

func isUpper(c byte) bool {
	return c >= 65 && c <= 90
}
func isLower(c byte) bool {
	return c >= 97 && c <= 122
}
func isNumber(c byte) bool {
	return c >= 48 && c <= 57
}
func isPalindrome(s string) bool {
	sByte, n := []byte(s), len(s)
	for i := 0; i < len(sByte); i++ {
		if isUpper(sByte[i]) {
			sByte[i] += 32
		}
	}
	i, j := 0, n-1
	for {
		for !(isLower(sByte[i]) || isNumber(sByte[i])) && i < j {
			i++
		}
		for !(isLower(sByte[j]) || isNumber(sByte[j])) && i < j {
			j--
		}
		if sByte[i] != sByte[j] {
			return false
		} else {
			i++
			j--
		}
		if i >= j {
			return true
		}
	}
}
func main() {
	fmt.Println(isPalindrome("A man, a plan, a canal: Panama"))
	fmt.Println(isPalindrome("race a car"))
	fmt.Println(isPalindrome(" "))
}
